/*******************************************************************************
 * Copyright (c) 2010 European Software Institute - Tecnalia.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *     Author - Adri�n Noguero (adrian.noguero@esi.es)
 *     
 *******************************************************************************/

package es.esi.gemde.modeltransformator.atlengine;

import org.eclipse.emf.ecore.EPackage;
import org.eclipse.jface.dialogs.Dialog;
import org.eclipse.jface.viewers.LabelProvider;
import org.eclipse.jface.viewers.ListViewer;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Shell;

/**
 * Dialog that reads the EMF metamodel registry and shows them in a list.
 *
 * @author Adri�n Noguero (adrian.noguero@esi.es)
 * @version 1.0
 * @since 1.0
 *
 */
public class MetamodelSelectionDialog extends Dialog {
	
	/* (non-Javadoc)
	 * @see org.eclipse.jface.window.Window#configureShell(org.eclipse.swt.widgets.Shell)
	 */
	@Override
	protected void configureShell(Shell newShell) {
		super.configureShell(newShell);
		newShell.setText("Select a metamodel from the list");
		newShell.setImage(ATLEngineActivator.getMetamodelIcon());
		newShell.setSize(300, 400);
	}

	/**
	 * Constructor. Calls the constructor of the superclass.
	 *
	 *@param parentShell the parent shell.
	 */
	public MetamodelSelectionDialog(Shell parentShell) {
		super(parentShell);
	}
	
	// Data properties
	EPackage metamodel;
	ListViewer viewer;
	
	/**
	 * This method returns the metamodel instance selected by the used using this dialog. Should be called after the {@link Dialog#open()} method.
	 * 
	 * @return the {@link EPackage} of the selected metamodel.
	 */
	public EPackage getSelectedMM () {
		return metamodel;
	}

	@Override
	protected void buttonPressed(int buttonId) {
		metamodel = (EPackage)((StructuredSelection)viewer.getSelection()).getFirstElement();
		super.buttonPressed(buttonId);
	}

	@Override
	protected Control createDialogArea(Composite parent) {
		Composite topPanel = (Composite)super.createDialogArea(parent);
		
		GridLayout layout = (GridLayout)topPanel.getLayout();
		layout.numColumns = 1;
		
		Label expLabel = new Label(topPanel, SWT.NONE);
		GridData labelData = new GridData(GridData.FILL_HORIZONTAL);
		expLabel.setLayoutData(labelData);
		expLabel.setText("Select the metamodel to be constrained:");
		
		viewer = new ListViewer(topPanel, SWT.SINGLE | SWT.BORDER | SWT.V_SCROLL| SWT.H_SCROLL);
		GridData listData = new GridData(GridData.FILL_BOTH);
		viewer.getList().setLayoutData(listData);
		viewer.setLabelProvider(listLabelProvider);
		
		// Read the EMF registry and fill in the list
		String [] registryKeys = EPackage.Registry.INSTANCE.keySet().toArray(new String [0]);
		for (int i = 0; i < registryKeys.length; i++) {
			if (EPackage.Registry.INSTANCE.get(registryKeys[i]) instanceof EPackage) {
				viewer.add(((EPackage)EPackage.Registry.INSTANCE.get(registryKeys[i])));
			}
			else if (EPackage.Registry.INSTANCE.get(registryKeys[i]) instanceof EPackage.Descriptor) {
				viewer.add(((EPackage.Descriptor)EPackage.Registry.INSTANCE.get(registryKeys[i])).getEPackage());
			}
		}
		
		return topPanel;
	}
	
	private LabelProvider listLabelProvider = new LabelProvider(){
		public Image getImage(Object element) {
			return null;
		}
		public String getText(Object element) {
			EPackage pack = null;
			
			try {
				if (element instanceof EPackage) {
					pack = (EPackage)element;
				}
				else if (element instanceof EPackage.Descriptor) {
					pack = ((EPackage.Descriptor)element).getEPackage();
				}
				else {
					return "Unknown type";
				}
			}
			catch (Exception e) {
				return "Exception Occurred";
			}
			return (pack.getName() + " : " + pack.getNsURI());
		}
	};
	
	

	

}
